home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 April / macformat-049.iso / mac / Shareware Plus / Developers / Mercutio MDEF v1.3.3 / Sample Codeƒ / MercutioDemoApp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-18  |  14.0 KB  |  604 lines  |  [TEXT/CWIE]

  1. /****************************************************************
  2.  
  3.     Test program for Mercutio MDEF 1.3
  4.     
  5.     by Ramon M. Felciano, Digital Alchemy
  6.     © 1992-1996, All Rights Reserved
  7.     
  8.     
  9. *****************************************************************/
  10.  
  11. /*
  12.  *    Changes:
  13.  *
  14.  *    06/11/96 : Uwe Hees
  15.  *    Added support for PPC callbacks by passing a UPP instead of a function address.
  16.  *     Fixed a bug in MyGetItemInfo (look for // ••)
  17.  */
  18. #include "MercutioAPI.h"
  19. #include "PopupDialog.h"
  20.  
  21. MenuHandle    appleMenu, fileMenu, editMenu, keysMenu,
  22.             iconsMenu, callbackMenu, colorMenu, xmnuMenu;
  23. MenuHandle    navigationMenu, dynamicSubMenu, functionKeyMenu, modifiersMenu, nonPrintingMenu,
  24.             japaneseMenu, arabicMenu, persianMenu;
  25. MenuHandle    ourPopupMenu;
  26.  
  27. Boolean    useKeyGraphics;
  28. enum    {
  29.     appleMenuID = 300,
  30.     fileMenuID,
  31.     editMenuID,
  32.     keysMenuID,
  33.     iconsMenuID,
  34.     callbackMenuID,
  35.     colorMenuID,
  36.     xmnuMenuID
  37.     };
  38.  
  39. enum    {
  40.     navigationMenuID = 1,
  41.     functionKeyMenuID,
  42.     dynamicSubMenuID,
  43.     modifiersMenuID,
  44.     nonPrintingMenuID,
  45.     japaneseMenuID,
  46.     arabicMenuID,
  47.     persianMenuID
  48.     };
  49.     
  50.  
  51. enum    {
  52.     popupDialogItem = 1,
  53.     separatorItem,
  54.     quitItem
  55.     };
  56.     
  57.     
  58. enum    {
  59.     addFolderIconID = 262,
  60.     addFoldersIconID,
  61.     addFileIconID,
  62.     addFilesIconID
  63.     };
  64.  
  65. pascal    void MyGetItemInfo (short menuID, short previousModifiers, RichItemData *itemData);
  66.  
  67. /****
  68.  * InitMacintosh()
  69.  *
  70.  * Initialize all the managers & memory
  71.  *
  72.  ****/
  73.  
  74. void InitMacintosh(void);
  75. void InitMacintosh(void)
  76.  
  77. {
  78.     MaxApplZone();
  79.     
  80.     InitGraf(&qd.thePort);
  81.     InitFonts();
  82.     FlushEvents(everyEvent, 0);
  83.     InitWindows();
  84.     InitMenus();
  85.     TEInit();
  86.     InitDialogs(0L);
  87.     InitCursor();
  88.  
  89. }
  90. /* end InitMacintosh */
  91.  
  92.  
  93. /****
  94.  * SetUpMenus()
  95.  *
  96.  *    Set up the menus. Normally, we’d use a resource file, but
  97.  *    for this example we’ll supply “hardwired” strings.
  98.  *
  99.  ****/
  100.  
  101. void SetUpMenus(void);
  102. void SetUpMenus(void)
  103.  
  104. {
  105.     MercutioCallbackUPP    myGetItemInfoUPP;
  106.     MenuPrefsRec    prefs;
  107.     
  108.     InsertMenu(appleMenu = GetMenu(appleMenuID), 0);
  109.     InsertMenu(fileMenu = GetMenu(fileMenuID), 0);
  110.     InsertMenu(editMenu = GetMenu(editMenuID), 0);
  111.     InsertMenu(keysMenu = GetMenu(keysMenuID), 0);
  112.     InsertMenu(iconsMenu = GetMenu(iconsMenuID), 0);
  113.     InsertMenu(callbackMenu = GetMenu(callbackMenuID), 0);
  114.     InsertMenu(colorMenu = GetMenu(colorMenuID), 0);
  115.     InsertMenu(xmnuMenu = GetMenu(xmnuMenuID), 0);
  116.     
  117.     InsertMenu(navigationMenu = GetMenu(navigationMenuID), -1);
  118.     InsertMenu(functionKeyMenu = GetMenu(functionKeyMenuID), -1);
  119.     InsertMenu(dynamicSubMenu = GetMenu(dynamicSubMenuID), -1);
  120.     InsertMenu(modifiersMenu = GetMenu(modifiersMenuID), -1);
  121.     InsertMenu(nonPrintingMenu = GetMenu(nonPrintingMenuID), -1);
  122.     InsertMenu(japaneseMenu = GetMenu(japaneseMenuID), -1);
  123.     InsertMenu(arabicMenu = GetMenu(arabicMenuID), -1);
  124.     InsertMenu(persianMenu = GetMenu(persianMenuID), -1);
  125.     
  126.     /*
  127.     **    In addition to the condense & extend bits, lets interpret shadow as the controlKey,
  128.     **    and outline as the callback flag.
  129.     */
  130.  
  131.     /*
  132.     
  133.     *** Setup the preferences for our menus *** 
  134.     
  135.     This is where we determine which style bits are mapped to 
  136.     MDEF features. Most of the menus use Mercutio's default 
  137.     settings. These menus are the exceptions. 
  138.     
  139.     Feel free to play with these settings and see how
  140.     the menus are affected.
  141.     
  142.     Note that we could have stored all this information in an
  143.     'Xmnu' resource with the same ID as the menu, and avoided 
  144.     the hassle of setting these preferences programmatically. 
  145.     We do it this way to demonstrate the various features of
  146.     the MDEF.
  147.  
  148.     */
  149.     
  150.     /*
  151.     
  152.     Set up the Color menu.
  153.     
  154.     The Color menu uses an 'Xmnu' resource to restore the Condense and Extend bits to their 
  155.     regular functions (as style bits), and sets the DEFAULT modifiers to Option-Command.
  156.     This means that key equivalents in this Menu need the Command and Option keys
  157.     held down, but all the style bits
  158.      are still free to be used as such. 
  159.     */
  160.     
  161.     prefs.optionKeyFlag.s = 0;
  162.     prefs.shiftKeyFlag.s = 0;
  163.     prefs.controlKeyFlag.s = 0;
  164.     prefs.cmdKeyFlag.s = 0;
  165.     prefs.isDynamicFlag.s = 0;
  166.     prefs.useCallbackFlag.s = 0;
  167.     prefs.forceNewGroupFlag.s = outline;
  168.     prefs.requiredModifiers = cmdKey + optionKey;
  169.  
  170.     MDEF_SetMenuPrefs(colorMenu, &prefs);
  171.     
  172.     
  173.     
  174.  
  175.     /*
  176.     
  177.     Set up the Modifiers menu.
  178.     
  179.     the Modifiers menu demonstrates all four modifier keys in action. Thus, we need
  180.     to use four style bits, which we select and store below.
  181.       
  182.     */
  183.     prefs.optionKeyFlag.s = underline;
  184.     prefs.shiftKeyFlag.s = extend;
  185.     prefs.cmdKeyFlag.s = bold;
  186.     prefs.controlKeyFlag.s = shadow;
  187.     prefs.isDynamicFlag.s = 0;
  188.     prefs.forceNewGroupFlag.s = 0;
  189.     prefs.useCallbackFlag.s = outline;
  190.     prefs.requiredModifiers = 0;
  191.  
  192.     MDEF_SetMenuPrefs(modifiersMenu, &prefs);
  193.     
  194.  
  195.  
  196.  
  197.     /*
  198.     
  199.     Set up the Callback menu.
  200.     
  201.     Note that we can make this call regardless of what MDEF we are using, 
  202.     because if an MDEF doesn't recognize a message (in our case, the 
  203.     SetCallback message), it simply ignores it.
  204.     
  205.     // •• Added support for PPC callbacks by passing a UPP instead of a
  206.     //    function address.
  207.     
  208.     */
  209.  
  210.     prefs.optionKeyFlag.s = condense;
  211.     prefs.shiftKeyFlag.s = extend;
  212.     prefs.cmdKeyFlag.s = 0; // was bold
  213.     prefs.controlKeyFlag.s = 0;
  214.     prefs.isDynamicFlag.s = outline;
  215.     prefs.forceNewGroupFlag.s = italic;
  216.     prefs.useCallbackFlag.s = underline;
  217.     prefs.requiredModifiers = cmdKey;
  218.     
  219.     myGetItemInfoUPP = NewMercutioCallback(MyGetItemInfo);
  220.     MDEF_SetCallbackProc(callbackMenu, myGetItemInfoUPP);
  221.     MDEF_SetMenuPrefs(callbackMenu, &prefs);
  222.     // We need to think about freeing the UPP here! This may
  223.     // not be too important b/c the normal app behavior should
  224.     // install the callback once and then it will be free'd
  225.     // automatically when the app quits.
  226.     
  227.     prefs.optionKeyFlag.s = condense;
  228.     prefs.shiftKeyFlag.s = extend;
  229.     prefs.cmdKeyFlag.s = 0;
  230.     prefs.controlKeyFlag.s = 0;
  231.     prefs.isDynamicFlag.s = outline;
  232.     prefs.forceNewGroupFlag.s = italic;
  233.     prefs.useCallbackFlag.s = 0;
  234.     prefs.requiredModifiers = cmdKey;
  235.     MDEF_SetMenuPrefs(dynamicSubMenu, &prefs);
  236.     
  237.     DrawMenuBar();
  238.  
  239. }
  240. /* end SetUpMenus */
  241.  
  242. //#define    gestaltSystemVersion    'sysv'
  243. //#define svAllSmallData    0x0000FF00
  244. //#define    svAllLargeData    0x000000FF
  245.  
  246. // appends one Pascal string to another
  247. void AppendPStr(StringPtr destStr, StringPtr sourceStr);
  248. void AppendPStr(StringPtr destStr, StringPtr sourceStr)
  249. {
  250.     short    len = sourceStr[0];
  251.     short    curLen = destStr[0];
  252.  
  253.     BlockMove(&sourceStr[1],&destStr[curLen+1],len);
  254.     destStr[0] = curLen+len;
  255. }
  256.  
  257. // copies one Pascal string onto another
  258. void CopyPStr(StringPtr destStr, StringPtr sourceStr);
  259. void CopyPStr(StringPtr destStr, StringPtr sourceStr)
  260. {
  261.     short    len = sourceStr[0];
  262.  
  263.     BlockMove(&sourceStr[0],&destStr[0],len+1);
  264. }
  265.  
  266.  
  267. pascal    void MyGetItemInfo (short menuID, short previousModifiers, RichItemData *itemData)
  268.     /*
  269.     This routine is used by the Callback menu to demonstrate the
  270.     Mercutio callback mechanism. This routine is called for every
  271.     item in the menu flagged as a "callback item" (in our case,
  272.     with the Outline style bit).
  273.     
  274.     In this example, we check the Shift and Option keys to
  275.     determine what the text and icon of the menu item should
  276.     be.
  277.     
  278.     Note the "Dirty" parameter; if we don't change anything
  279.     in the menuItem, this parameter should be false to
  280.     avoid unnecessary redrawing (and flicker).
  281.     */
  282. {
  283.  
  284.      OSErr    theErr = noErr;
  285.     short    modifiers = 0;
  286.     long    currentTicks;
  287.     Str255    tickStr;
  288.     EventRecord    theEvent;
  289.     Boolean    temp;
  290.     
  291.     temp = EventAvail(everyEvent, &theEvent);
  292.     modifiers = theEvent.modifiers;
  293.  
  294.     if (menuID == callbackMenuID) {
  295.         if (itemData->itemID == 37) {
  296.             switch (itemData->cbMsg)
  297.               {
  298.               case cbBasicDataOnlyMsg:              
  299.                 if (modifiers & shiftKey) {
  300.                     itemData->flags = (itemData->flags | kShiftKey);
  301.                     if (modifiers & optionKey) {    // •• I think there was a bug here. This line was originally:
  302. //                    if (modifiers, optionKey) {
  303.                         itemData->flags = itemData->flags | kOptionKey;
  304.                         CopyPStr(itemData->itemStr, "\pAdd Folders…");
  305.                     } else {
  306.                         CopyPStr(itemData->itemStr, "\pAdd Folder…");
  307.                     }
  308.                 } else {
  309.                     if (modifiers & optionKey) {
  310.                         itemData->flags = itemData->flags | kOptionKey;
  311.                         CopyPStr(itemData->itemStr, "\pAdd Files…");
  312.                     } else {
  313.                         CopyPStr(itemData->itemStr, "\pAdd File…");
  314.                     }
  315.                 
  316.                 }
  317.                   if (modifiers != previousModifiers) {
  318.                       itemData->flags = itemData->flags | kChangedByCallback;
  319.                   }
  320.                   itemData->flags = itemData->flags | kHasIcon;
  321.                   break;
  322.     
  323.               case    cbIconOnlyMsg:
  324.                 if (modifiers & shiftKey) {
  325.                     if (modifiers, optionKey) {
  326.                         itemData->hIcon = (Handle) GetCIcon(addFoldersIconID);
  327.                     } else {
  328.                         itemData->hIcon = (Handle) GetCIcon(addFolderIconID);
  329.                     }
  330.                 } else {
  331.                     if (modifiers, optionKey) {
  332.                         itemData->hIcon = (Handle) GetCIcon(addFilesIconID);
  333.                     } else {
  334.                         itemData->hIcon = (Handle) GetCIcon(addFileIconID);
  335.                     }
  336.                 
  337.                 }
  338.     
  339.                   itemData->iconType = 'cicn';
  340.                   itemData->flags = itemData->flags | kHasIcon;
  341.                   
  342.                 //    The item has changed if the user is holding down a new set of modifiers
  343.                   if (modifiers != previousModifiers) {
  344.                       itemData->flags = itemData->flags | kChangedByCallback;
  345.                   }
  346.                   
  347.                 break;
  348.             
  349.               case    cbGetLongestItemMsg:
  350.                 CopyPStr(itemData->itemStr, "\pAdd Folders…");
  351.                   itemData->flags = itemData->flags | kShiftKey;
  352.                   itemData->flags = itemData->flags | kOptionKey;
  353.                 break;
  354.             
  355.               }
  356.         }
  357.         if (itemData->itemID == 38) {
  358.             switch (itemData->cbMsg)
  359.               {
  360.               case cbBasicDataOnlyMsg:
  361.                   currentTicks = TickCount();
  362.                   NumToString(currentTicks, tickStr);
  363.                   CopyPStr(itemData->itemStr, "\pTicks: ");
  364.                 AppendPStr(itemData->itemStr, tickStr);
  365.                   itemData->flags = itemData->flags | kChangedByCallback;
  366.                   break;
  367.     
  368.               case    cbIconOnlyMsg:
  369.                 break;
  370.             
  371.               case    cbGetLongestItemMsg:
  372.                   CopyPStr(itemData->itemStr, "\pTicks: 9999999999");
  373.                 break;
  374.               }
  375.         }
  376.     }
  377.  
  378.     
  379. }
  380.  
  381.  
  382.  
  383.  
  384. // int enable (MenuHandle menu, short item, short ok);
  385.  
  386.  
  387. /*****
  388.  * ToggleItem()
  389.  *
  390.  *    Turn the checkmark of a given item on or off.
  391.  *
  392.  *****/
  393.  
  394.  
  395. void ToggleItem (MenuHandle menu, short item);
  396. void ToggleItem (MenuHandle menu, short item)
  397. {
  398.     short    curMark;
  399.     
  400.     GetItemMark(menu, item, &curMark);
  401.     if (curMark == noMark)
  402.         CheckItem(menu, item, TRUE);
  403.     else
  404.         CheckItem(menu, item, FALSE);
  405. }
  406.  
  407.  
  408. /*****
  409.  * HandleMenu(mSelect)
  410.  *
  411.  *    Handle the menu selection. mSelect is what MenuSelect() and
  412.  *    MenuKey() return: the high word is the menu ID, the low word
  413.  *    is the menu item
  414.  *
  415.  *****/
  416.  
  417. void HandleMenu (long mSelect);
  418. void HandleMenu (long mSelect)
  419.  
  420. {
  421.     int            menuID = HiWord(mSelect);
  422.     int            itemNum = LoWord(mSelect);
  423.     short        dummy;
  424.     Str255        name;
  425.     GrafPtr        savePort;
  426.     DialogPtr    AboutDLOG;
  427.     DialogRecord AboutRecord;
  428.     StringHandle    theCopyright;
  429.     short        markChar;
  430.     int            i = 0;
  431.     
  432.     switch (menuID) {
  433.         case appleMenuID:
  434.             switch (itemNum) {
  435.                 case 1 :
  436.                     theCopyright = MDEF_GetCopyright(modifiersMenu);
  437.                     AboutDLOG = GetNewDialog(3000, &AboutRecord, (WindowPtr) (-1));
  438.                     ParamText(*theCopyright,0L,0L,0L);
  439.                     ModalDialog(0L, &dummy);
  440.                     CloseDialog(AboutDLOG);
  441.                     DisposeHandle ((Handle)theCopyright);
  442.                     break;
  443.                 
  444.                 default :
  445.                     GetPort(&savePort);
  446.                     GetItem(appleMenu, itemNum, name);
  447.                     OpenDeskAcc(name);
  448.                     SetPort(savePort);
  449.                     break;
  450.                 }
  451.             break;
  452.         
  453.         case fileMenuID:
  454.             switch (itemNum) {
  455.                 case popupDialogItem:
  456.                     doPopupDialog();
  457.                     break;
  458.  
  459.                 case quitItem:
  460.                     ExitToShell();
  461.                     break;
  462.               }
  463.             break;
  464.                   
  465.         case editMenuID:
  466.             if (!SystemEdit(itemNum-1))
  467.                 SysBeep(5);
  468.             break;
  469.                 
  470.         case iconsMenuID:
  471.             if (itemNum == 6) {
  472.                 GetItemMark(iconsMenu, itemNum, &markChar);
  473.                 for (i = 7 ; i <= CountMItems(iconsMenu); i++) {
  474.                     if (markChar == 0) {
  475.                         EnableItem(iconsMenu, i);
  476.                     } else {
  477.                         DisableItem(iconsMenu, i);
  478.                     }
  479.                 }
  480.             }
  481.             ToggleItem (iconsMenu, itemNum);
  482.             break;
  483.         
  484.         case keysMenuID:
  485.             if (itemNum == 5) {
  486.                 useKeyGraphics = !useKeyGraphics;
  487.                 MDEF_SetKeyGraphicsPreference(nonPrintingMenu, useKeyGraphics);
  488.                 ToggleItem (nonPrintingMenu, itemNum);
  489.             } else {
  490.                 ToggleItem (nonPrintingMenu, itemNum);
  491.             }
  492.             break;
  493.         
  494.         case callbackMenuID:    ToggleItem (callbackMenu, itemNum); break;
  495.         case colorMenuID:        ToggleItem (colorMenu, itemNum); break;
  496.         case xmnuMenuID:        ToggleItem (xmnuMenu, itemNum); break;
  497.         case navigationMenuID:    ToggleItem (navigationMenu, itemNum);    break;
  498.         case functionKeyMenuID:    ToggleItem (functionKeyMenu, itemNum);    break;
  499.         case dynamicSubMenuID:    ToggleItem (dynamicSubMenu, itemNum);    break;
  500.         case modifiersMenuID:    ToggleItem (modifiersMenu, itemNum);    break;
  501.         case nonPrintingMenuID:    ToggleItem (nonPrintingMenu, itemNum);    break;
  502.         case japaneseMenuID:    ToggleItem (japaneseMenu, itemNum);    break;
  503.         case arabicMenuID:        ToggleItem (arabicMenu, itemNum);    break;
  504.         case persianMenuID:        ToggleItem (persianMenu, itemNum);    break;    
  505.         
  506.       }
  507. }
  508. /* end HandleMenu */
  509.  
  510.  
  511.  
  512.  
  513.  
  514. /****
  515.  * HandleEvent()
  516.  *
  517.  *        The main event dispatcher. This routine should be called
  518.  *        repeatedly (it  handles only one event).
  519.  *
  520.  *****/
  521.  
  522. void HandleEvent(void);
  523. void HandleEvent(void)
  524.  
  525. {
  526.     int    windowCode;
  527.     EventRecord    theEvent;
  528.     WindowPtr    theWindow;
  529.  
  530.     HiliteMenu(0);
  531.     SystemTask ();        /* Handle desk accessories */
  532.     
  533.     if (GetNextEvent (everyEvent, &theEvent))
  534.       switch (theEvent.what)
  535.         {
  536.         case mouseDown:
  537.             windowCode = FindWindow(theEvent.where, &theWindow);
  538.     
  539.             switch (windowCode)
  540.               {
  541.               case inSysWindow: 
  542.                 SystemClick (&theEvent, theWindow);
  543.                 break;
  544.         
  545.               case inMenuBar:
  546.                   HandleMenu(MenuSelect(theEvent.where));
  547.                 break;
  548.         
  549.               }
  550.               break;
  551.  
  552.             
  553.         case keyDown: 
  554.         case autoKey:
  555.             /*
  556.                 This codes is commented out in order to get the Modifiers menu
  557.                 to work (it doesn't require the commandKey to be held down.
  558.                 
  559.                 You may want to use a check like this in your code to speed
  560.                 up processing.
  561.             */
  562.             // if ((theEvent.modifiers & cmdKey) != 0)
  563.             //   {
  564.               HandleMenu(MDEF_MenuKey(theEvent.message,theEvent.modifiers,modifiersMenu));
  565.             //  }
  566.             break;
  567.                 
  568.         }
  569. }
  570. /* end HandleEvent */
  571.  
  572.  
  573.  
  574.  
  575.  
  576. /*****
  577.  * main()
  578.  *
  579.  *    This is where everything happens
  580.  *
  581.  *****/
  582.  
  583. main()
  584.  
  585. {
  586.  
  587.     StringHandle    theCopyright;
  588.     long    theVersion;
  589.     
  590.     InitMacintosh();
  591.     SetUpMenus();
  592.     
  593.     //theVersion = long(MDEF_GetCopyright(modifiersMenu));
  594.     theVersion = MDEF_GetVersion(modifiersMenu);
  595.     theCopyright = MDEF_GetCopyright(modifiersMenu);
  596.     DisposeHandle ((Handle)theCopyright);
  597.     
  598.     for (;;)
  599.         HandleEvent();
  600.  
  601.     // we don't need to dispose of the menuHandles since we're quitting the application
  602.         
  603. }
  604.